import logging
from logging.handlers import TimedRotatingFileHandler
import time
import os


class CommonTimedRotatingFileHandler(TimedRotatingFileHandler):
    @property
    def dfn(self):
        currentTime = int(time.time())
        # get the time that this sequence started at and make it a TimeTuple
        dstNow = time.localtime(currentTime)[-1]
        t = self.rolloverAt - self.interval
        if self.utc:
            timeTuple = time.gmtime(t)
        else:
            timeTuple = time.localtime(t)
            dstThen = timeTuple[-1]
            if dstNow != dstThen:
                if dstNow:
                    addend = 3600
                else:
                    addend = -3600
                timeTuple = time.localtime(t + addend)
        dfn = self.rotation_filename(self.baseFilename + "." + time.strftime(self.suffix, timeTuple))
        return dfn

    def shouldRollover(self, record):
        """
        是否应该执行日志滚动操作：
        1、存档文件已存在时，执行滚动操作
        2、当前时间 >= 滚动时间点时，执行滚动操作
        """
        dfn = self.dfn
        t = int(time.time())
        if t >= self.rolloverAt or os.path.exists(dfn):
            return 1
        return 0

    def doRollover(self):
        """
        执行滚动操作
        1、文件句柄更新
        2、存在文件处理
        3、备份数处理
        4、下次滚动时间点更新
        """
        if self.stream:
            self.stream.close()
            self.stream = None
        # get the time that this sequence started at and make it a TimeTuple
        dfn = self.dfn
        # 存档log 已存在处理
        if not os.path.exists(dfn):
            self.rotate(self.baseFilename, dfn)

        # 备份数控制
        if self.backupCount > 0:
            for s in self.getFilesToDelete():
                os.remove(s)

        # 延迟处理
        if not self.delay:
            self.stream = self._open()

        # 更新滚动时间点
        currentTime = int(time.time())
        newRolloverAt = self.computeRollover(currentTime)
        while newRolloverAt <= currentTime:
            newRolloverAt = newRolloverAt + self.interval

        # If DST changes and midnight or weekly rollover, adjust for this.
        if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
            dstAtRollover = time.localtime(newRolloverAt)[-1]
            dstNow = time.localtime(currentTime)[-1]
            if dstNow != dstAtRollover:
                if not dstNow:  # DST kicks in before next rollover, so we need to deduct an hour
                    addend = -3600
                else:  # DST bows out before next rollover, so we need to add an hour
                    addend = 3600
                newRolloverAt += addend
        self.rolloverAt = newRolloverAt


class MyTimedRotatingFileHandler(TimedRotatingFileHandler):
    def rotate(self, source, destination):
        if not callable(self.rotator):
            # Issue 18940: A file may not have been created if delay is True.
            self.new_rename(destination, source)
        else:
            self.rotator(source, destination)

    @staticmethod
    def new_rename(destination, source):
        """
            rename file Permission Error, So open new file, write the old file to new file,
             and then empty the old file.
        """
        if os.path.exists(source):
            with open(destination, "w+") as fw:
                with open(source, "r+") as fr:
                    fw.write(fr.read())
            with open(source, "w+") as fw:
                fw.write("###\n")


class Logs(object):
    def __init__(self, name=None):
        self.name = name
        self.logger = logging.getLogger(self.name)
        self.logger.setLevel(logging.DEBUG)
        # log_path
        logs_dir = "logs"
        # loggerpid = str(os.getpid())
        if os.path.exists(logs_dir) and os.path.isdir(logs_dir):
            pass
        else:
            os.mkdir(logs_dir)
        # log_path
        # timestamp = time.strftime("%H%M%S_%Y-%m-%d")
        # timestamp = time.strftime("%Y-%m-%d")
        logfile_name = f'current_log.log'
        logfile_path = os.path.join(logs_dir, logfile_name)
        file_handler = MyTimedRotatingFileHandler(filename=logfile_path, when='MIDNIGHT', backupCount=30)
        # log_format
        formatter = logging.Formatter('[%(asctime)s] [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s')

        file_handler.setFormatter(formatter)
        # console output
        self.console = logging.StreamHandler()
        self.console.setFormatter(formatter)
        self.console.setLevel(logging.DEBUG)
        file_handler.setLevel(logging.INFO)
        # file output
        self.logger.addHandler(file_handler)
        self.logger.addHandler(self.console)

    def get_logger(self):
        return self.logger


# if __name__ == '__main__':
#     logger = Logs().get_logger()
#     logger.info('hahah')
#     logger.debug('heihei')
